package com.john.blockchain.demo.mock.task;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author jiangguangtao 2018/4/14
 */
public class HashCalcTaskContext {
    private static final Logger LOGGER = LoggerFactory.getLogger(HashCalcTaskContext.class);

    private CountDownLatch latch;

    /**
     * 任务是否在继续执行
     */
    private boolean taskRunning = true;
    /**
     * 存储附加数的队列
     */
    private BlockingQueue<String> nonceQueue;
    /**
     * 计算次数累加器
     */
    private AtomicLong calcTimes = new AtomicLong(0);
    /**
     * 待计算的原始字符串
     */
    private String originString;
    /**
     * 匹配字符串码 0000000000
     */
    private String findCode = "0000000000";
    /**
     * 半匹配的字符串码 000000 用于日志输出的
     */
    private String halfFindCode = "000000";
    /**
     * 结果Hash
     */
    private String resultHash;

    /**
     * 计算任务上下文环境变量
     *
     * @param latch        任务线程结束标识 只统计计算任务线程
     * @param nonceQueue   随机数保存队列
     * @param originString 计算hash的原始字符串
     */
    public HashCalcTaskContext(CountDownLatch latch, BlockingQueue<String> nonceQueue, String originString) {
        this.latch = latch;
        this.nonceQueue = nonceQueue;
        this.originString = originString;
        setMatchCodeLength(10);
    }

    /**
     * 设置匹配字符串长度
     * <p>
     * 最小为4 最大不超过10
     *
     * @param matchCodeLength 匹配字符串长度 最小为4 最大不超过10
     */
    public void setMatchCodeLength(int matchCodeLength) {
        if (matchCodeLength < 4) {
            matchCodeLength = 4;
        }
        if (matchCodeLength > 10) {
            matchCodeLength = 10;
        }

        halfFindCode = StringUtils.repeat("0", matchCodeLength - 1);
        findCode = halfFindCode + "0";
    }


    public boolean isTaskRunning() {
        return taskRunning;
    }

    /**
     * 计算任务结果
     */
    public void finishTask(String resultHash) {
        if (this.taskRunning) {
            this.taskRunning = false;
            this.resultHash = resultHash;
        } else {
            System.out.println("重复的计算结果：" + resultHash);
        }
    }

    public BlockingQueue<String> getNonceQueue() {
        return nonceQueue;
    }

    public void setNonceQueue(BlockingQueue<String> nonceQueue) {
        this.nonceQueue = nonceQueue;
    }

    public Long getNextCalcTimes() {
        return calcTimes.incrementAndGet();
    }

    public String getOriginString() {
        return originString;
    }

    public void setOriginString(String originString) {
        this.originString = originString;
    }

    public String getFindCode() {
        return findCode;
    }

    public String getHalfFindCode() {
        return halfFindCode;
    }

    public CountDownLatch getLatch() {
        return latch;
    }

    public Long getCalcTimes() {
        return calcTimes.get();
    }

    public String getResultHash() {
        return resultHash;
    }
}
